﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Google.API.Translate;

namespace Granslator
{
    public partial class frmWizard : Form
    {
        public frmWizard()
        {
            InitializeComponent();
        }

        private List<string> OriginalText = new List<string>();
        private List<string> GoogleTranslation = new List<string>();
        private List<string> YourTranslation = new List<string>();

        private int Pos = 0;

        #region Properties

        public string SourceText
        {
            get { return txtSource.Text; }
            set { txtSource.Text = value; }
        }

        public string Source
        {
            get;
            set;
        }

        public int SourceLanguage
        {
            get { return cboSource.SelectedIndex; }
            set { cboSource.SelectedIndex = value; }
        }

        public int TargetLanuage
        {
            get { return cboTarget.SelectedIndex; }
            set { cboTarget.SelectedIndex = value; }
        }

        public string Result
        {
            get { return txtResult.Text; }
        }

        public bool ReplcaeResultsInMainForm
        {
            get { return chkLoadToMainForm.Checked; }
            set { chkLoadToMainForm.Checked = value; }
        }

        public bool SavedToFile
        {
            get;
            set;
        }

        public bool Saved
        {
            get;
            set;
        }

        public string Filename
        {
            get;
            set;
        }

        #endregion

        private void lblSwap_Click(object sender, EventArgs e)
        {
            int i = cboSource.SelectedIndex;
            cboSource.SelectedIndex = cboTarget.SelectedIndex;
            cboTarget.SelectedIndex = i;
        }

        private void lblOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog Opendlg = new OpenFileDialog();
            Opendlg.DefaultExt = "txt";
            Opendlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            if (Opendlg.ShowDialog() == DialogResult.OK)
            {
                StreamReader reader = File.OpenText(Opendlg.FileName);
                txtSource.Text = reader.ReadToEnd();
            }
            Opendlg.Dispose();
        }

        /// <summary>
        /// Convert a List of strings to a string
        /// </summary>
        /// <param name="items">List of strings</param>
        /// <returns>a string contained all items in list</returns>
        private string ConvertListToString(List<string> items)
        {
            string result = string.Empty;
            foreach (string a in items)
            {
                result += a + ' ' ;
            }
            return result;
        }

        /// <summary>
        /// Split text to sentences
        /// </summary>
        /// <param name="Text">Text to parse</param>
        /// <returns>a list of sentences</returns>
        private List<string> ParseSentences(string Text)
        {
            List<string> result = new List<string>();
            string tmp = Text;
            tmp = tmp.Replace(Environment.NewLine, " ");

            //sentence terminations
            char[] arrSplitChars = { '.', '?', '!' };

            string[] splitSentences = tmp.Split(arrSplitChars, StringSplitOptions.RemoveEmptyEntries);
            
            for (int i = 0; i < splitSentences.Length; i++)
            {
                int pos = tmp.IndexOf(splitSentences[i].ToString());
                char[] arrChars = tmp.Trim().ToCharArray();
                int termPos = pos + splitSentences[i].Length;
                char c = 'c';
                if (termPos <= arrChars.Length - 1)
                {
                    c = arrChars[termPos];
                    result.Add(splitSentences[i].ToString().Trim() + c.ToString());
                }
                else
                    result.Add(splitSentences[i].ToString().Trim());
            }

            return result;
        }


        private List<string> GetSentences(string Text)
        {
            List<string> result = new List<string>();
            foreach (string a in Text.Split('.'))
            {
                result.Add(a);
            }
            return result;
        }

        /// <summary>
        /// Translate input text using translate.google.com
        /// </summary>
        /// <param name="TextToTanslate">Text To Tanslate</param>
        /// <param name="from">Source Language</param>
        /// <param name="to">Target Language</param>
        private string TranslateByGoogle(string TextToTanslate,int from, int to)
        {
            Language LanguageFrom = Language.Unknown;
            Language LanguageTo = Language.Unknown;

            switch (from)
            {
                case 0: LanguageFrom = Language.Arabic;
                    break;
                case 1: LanguageFrom = Language.Bulgarian;
                    break;
                case 2: LanguageFrom = Language.Chinese;
                    break;
                case 3: LanguageFrom = Language.Croatian;
                    break;
                case 4: LanguageFrom = Language.Czech;
                    break;
                case 5: LanguageFrom = Language.Danish;
                    break;
                case 6: LanguageFrom = Language.Dutch;
                    break;
                case 7: LanguageFrom = Language.English;
                    break;
                case 8: LanguageFrom = Language.Finnish;
                    break;
                case 9: LanguageFrom = Language.French;
                    break;
                case 10: LanguageFrom = Language.German;
                    break;
                case 11: LanguageFrom = Language.Greek;
                    break;
                case 12: LanguageFrom = Language.Hindi;
                    break;
                case 13: LanguageFrom = Language.Italian;
                    break;
                case 14: LanguageFrom = Language.Japanese;
                    break;
                case 15: LanguageFrom = Language.Korean;
                    break;
                case 16: LanguageFrom = Language.Norwegian;
                    break;
                case 17: LanguageFrom = Language.Persian;
                    break;
                case 18: LanguageFrom = Language.Polish;
                    break;
                case 19: LanguageFrom = Language.Portuguese;
                    break;
                case 20: LanguageFrom = Language.Romanian;
                    break;
                case 21: LanguageFrom = Language.Russian;
                    break;
                case 22: LanguageFrom = Language.Spanish;
                    break;
                case 23: LanguageFrom = Language.Swedish;
                    break;
            }

            switch (to)
            {
                case 0: LanguageTo = Language.Arabic;
                    break;
                case 1: LanguageTo = Language.Bulgarian;
                    break;
                case 2: LanguageTo = Language.Chinese;
                    break;
                case 3: LanguageTo = Language.Croatian;
                    break;
                case 4: LanguageTo = Language.Czech;
                    break;
                case 5: LanguageTo = Language.Danish;
                    break;
                case 6: LanguageTo = Language.Dutch;
                    break;
                case 7: LanguageTo = Language.English;
                    break;
                case 8: LanguageTo = Language.Finnish;
                    break;
                case 9: LanguageTo = Language.French;
                    break;
                case 10: LanguageTo = Language.German;
                    break;
                case 11: LanguageTo = Language.Greek;
                    break;
                case 12: LanguageTo = Language.Hindi;
                    break;
                case 13: LanguageTo = Language.Italian;
                    break;
                case 14: LanguageTo = Language.Japanese;
                    break;
                case 15: LanguageTo = Language.Korean;
                    break;
                case 16: LanguageTo = Language.Norwegian;
                    break;
                case 17: LanguageTo = Language.Persian;
                    break;
                case 18: LanguageTo = Language.Polish;
                    break;
                case 19: LanguageTo = Language.Portuguese;
                    break;
                case 20: LanguageTo = Language.Romanian;
                    break;
                case 21: LanguageTo = Language.Russian;
                    break;
                case 22: LanguageTo = Language.Spanish;
                    break;
                case 23: LanguageTo = Language.Swedish;
                    break;
            }
            return Translator.Translate(TextToTanslate, LanguageFrom, LanguageTo);
        }

        private List<string> TranslateAll()
        {
            List<string> result = new List<string>();
            foreach (string a in OriginalText)
            {
                result.Add(TranslateByGoogle(a, cboSource.SelectedIndex, cboTarget.SelectedIndex));
            }
            return result;
        }

        private void DetectSourceLanguage()
        {
            bool reliable = false;
            double d = 0;
            Language l = Language.Unknown;
            this.Enabled = false;
                l = Translator.Detect(txtSource.Text, out reliable, out d);
                    switch (l)
                    {
                        case Language.Arabic: cboSource.SelectedIndex = 0;
                            break;
                        case Language.Bulgarian: cboSource.SelectedIndex = 1;
                            break;
                        case Language.Chinese: cboSource.SelectedIndex = 2;
                            break;
                        case Language.Croatian: cboSource.SelectedIndex = 3; ;
                            break;
                        case Language.Czech: cboSource.SelectedIndex = 4; ;
                            break;
                        case Language.Danish: cboSource.SelectedIndex = 5;
                            break;
                        case Language.Dutch: cboSource.SelectedIndex = 6;
                            break;
                        case Language.English: cboSource.SelectedIndex = 7;
                            break;
                        case Language.Finnish: cboSource.SelectedIndex = 8;
                            break;
                        case Language.French: cboSource.SelectedIndex = 9;
                            break;
                        case Language.German: cboSource.SelectedIndex = 10;
                            break;
                        case Language.Greek: cboSource.SelectedIndex = 11;
                            break;
                        case Language.Hindi: cboSource.SelectedIndex = 12;
                            break;
                        case Language.Italian: cboSource.SelectedIndex = 13;
                            break;
                        case Language.Japanese: cboSource.SelectedIndex = 14;
                            break;
                        case Language.Korean: cboSource.SelectedIndex = 15;
                            break;
                        case Language.Norwegian: cboSource.SelectedIndex = 16;
                            break;
                        case Language.Persian: cboSource.SelectedIndex = 17;
                            break;
                        case Language.Polish: cboSource.SelectedIndex = 18;
                            break;
                        case Language.Portuguese: cboSource.SelectedIndex = 19;
                            break;
                        case Language.Romanian: cboSource.SelectedIndex = 20;
                            break;
                        case Language.Russian: cboSource.SelectedIndex = 21;
                            break;
                        case Language.Spanish: cboSource.SelectedIndex = 22;
                            break;
                        case Language.Swedish: cboSource.SelectedIndex = 23;
                            break;
                    }
                this.Enabled = true;
        }
        
        private void chkDetect_CheckedChanged(object sender, EventArgs e)
        {
            if (chkDetect.Checked)
            {
                cboSource.Enabled = false;
                lblSwap.Enabled = false;
            }
            else
            {
                cboSource.Enabled = true;
                lblSwap.Enabled = true;
            }
        }

        private void HideSteps()
        {
            Step1.Hide();
            Step2.Hide();
            Step3.Hide();
            Step4.Hide();
        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            if (Step1.Visible)
            {
                if (cboSource.SelectedIndex == cboTarget.SelectedIndex)
                {
                    if (!chkDetect.Checked)
                    {
                        MessageBox.Show("Source and Target languages cannot be same.", "Error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                HideSteps();
                Step2.Show();
                txtSource.Focus();
                Step2.Location = new Point(Step1.Left, Step1.Top);
                btnBack.Enabled = true;
                return;
            }
            if (Step2.Visible)
            {
                if (txtSource.Text.Trim() == string.Empty)
                {
                    MessageBox.Show("Enter somethin first", "Translate Wizard",
                        MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                OriginalText = ParseSentences(txtSource.Text);
                this.Enabled = false;
                if (chkDetect.Checked)
                {
                    try
                    {
                        DetectSourceLanguage();
                    }
                    catch
                    {
                        MessageBox.Show("Language detection faild. Check if you are connected to internet or not, then try again.",
                            "Language Detection", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.Enabled = true;
                        return;
                    }
                }
                if (Source != txtSource.Text)
                {
                    try
                    {
                        GoogleTranslation = TranslateAll();
                    }
                    catch
                    {
                        MessageBox.Show("Translate faild.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.Enabled = true;
                        txtSource.Focus();
                        return;
                    }
                    Source = txtSource.Text;
                }
                YourTranslation = GoogleTranslation;
                HideSteps();
                this.Enabled = true;
                Step3.Show();
                Step3.Location = new Point(Step1.Left, Step1.Top);
                txtOriginal.Text = OriginalText[0];
                txtGoogle.Text = GoogleTranslation[0];
                txtYou.Text = YourTranslation[0];
                Pos = 1;
                return;
            }
            if (Step3.Visible)
            {
                if (txtYou.Text == string.Empty)
                {
                    MessageBox.Show("Enter something first.");
                    txtYou.Focus();
                    return;
                }
                if (Pos == OriginalText.Count)
                {
                    HideSteps();
                    Step4.Show();
                    txtResult.Text = ConvertListToString(YourTranslation);
                    Step4.Location = new Point(Step1.Left, Step1.Top);
                    btnNext.Text = "&Finish";
                    return;
                }   
                txtOriginal.Text = OriginalText[Pos];
                txtGoogle.Text = GoogleTranslation[Pos];
                txtYou.Text = YourTranslation[Pos];
                Pos += 1;
                return;
            }
            if (Step4.Visible)
            {
                if (ReplcaeResultsInMainForm)
                {
                    Close();
                    return;
                }
                if (!Saved)
                {
                    if (SavedToFile)
                    {
                        if (MessageBox.Show("Do you want to save changes you made to '" + Filename + "'?", "Save"
                            , MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            File.WriteAllText(Filename, Result, Encoding.UTF8);
                            Close();
                        }
                        else
                        {
                            Close();
                        }
                    }
                    else
                    {
                        if (MessageBox.Show("Do you want to save changes you made to a file?", "Save"
                            , MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            lblSave_Click(null, null);
                            Close();
                        }
                    }
                }
                else
                {
                    Close();
                }
            }
        }

        private void frmWizard_Load(object sender, EventArgs e)
        {
            txtGoogle.ReadOnly = true;
            txtOriginal.ReadOnly = true;
            ReplcaeResultsInMainForm = true;
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            if (Step2.Visible)
            {
                HideSteps();
                Step1.Show();
                btnBack.Enabled = false;
                return;
            }
            if (Step3.Visible)
            {
                if (Pos > 0)
                {
                    Pos -= 1;
                    txtOriginal.Text = OriginalText[Pos];
                    txtGoogle.Text = GoogleTranslation[Pos];
                    txtYou.Text = YourTranslation[Pos];
                }
                else
                {
                    HideSteps();
                    Step2.Show();
                }
                return;
            }
            if (Step4.Visible)
            {
                HideSteps();
                Step3.Show();
                Pos -= 1;
                txtOriginal.Text = OriginalText[Pos];
                txtGoogle.Text = GoogleTranslation[Pos];
                txtYou.Text = YourTranslation[Pos];
                btnNext.Text = "&Next";
                return;
            }
        }

        private void lblSave_Click(object sender, EventArgs e)
        {
            SaveFileDialog Savedlg = new SaveFileDialog();
            Savedlg.DefaultExt = "txt";
            Savedlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            if (Savedlg.ShowDialog() == DialogResult.OK)
            {
                Filename = Savedlg.FileName;
                File.WriteAllText(Filename, Result, Encoding.UTF8);
                SavedToFile = true;
                Saved = true;
            }
        }

        private void txtResult_TextChanged(object sender, EventArgs e)
        {
            Saved = false;
        }
    }
}

